<template>
  <div class="app-container calendar-list-container">
    <!--条件查询-->
    <div class="filter-container">
      <el-input  clearable style="width: 130px;" class="filter-item" v-model="query.username" :placeholder="'用户名'">
      </el-input>
      <el-input  clearable style="width: 130px;" class="filter-item" v-model="query.realname" :placeholder="'真实姓名'">
      </el-input>
      <el-input  clearable style="width: 130px;" class="filter-item" v-model="query.phone" :placeholder="'手机号'">
      </el-input>
      <el-input  clearable style="width: 130px;" class="filter-item" v-model="query.email" :placeholder="'邮箱'">
      </el-input>
      <el-select clearable style="width: 110px" class="filter-item" v-model="query.sex" :placeholder="'性别'">
        <el-option v-for="item in sex" :key="item" :label="item == 1 ? '女':'男'" :value="item">
        </el-option>
      </el-select>
      <el-select
        clearable
        class="filter-item"
        style="width: 110px"
        v-model="query.organizationId"
        filterable
        remote
        reserve-keyword
        placeholder="所属组织"
        :remote-method="remoteMethod"
        :loading="loading">
        <el-option
          v-for="item in orgs"
          :key="item.id"
          :label="item.name"
          :value="item.id">
        </el-option>
      </el-select>
      <el-button class="filter-item" style="margin-left: 10px;" type="primary" v-waves icon="el-icon-search" @click="getList">{{$t('table.search')}}</el-button>
      <el-button class="filter-item" style="margin-left: 10px;" @click="handleCreate" type="primary" icon="el-icon-edit">{{$t('table.add')}}</el-button>
      <el-button class="filter-item" style="margin-left: 10px;" @click="handleDelete" type="danger" icon="el-icon-delete">{{$t('table.delete')}}</el-button>
      <div>
        <!--角色授权-->
        <el-button plain size="mini" type="primary" round @click="handlerGrantAuthorization()">{{'角色授权'}}</el-button>
        <!--编辑组织-->
        <el-button plain type="info" size="mini" round @click="editOrg">{{'编辑组织'}}</el-button>
      </div>
    </div>
    <!--带边框的表格-->
    <el-table
      :data="tableData"
      border
      v-loading="listLoading" element-loading-text="拼命加载中"
      @selection-change="handleSelectionChange"
      style="width: 100%">
      <!--展开显示详情-->
      <el-table-column
        type="expand">
        <template slot-scope="props">
          <el-form label-position="left" inline class="demo-table-expand">
            <el-form-item label="用户id">
              <span>{{ props.row.id }}</span>
            </el-form-item>
            <el-form-item label="用户名">
              <span>{{ props.row.username }}</span>
            </el-form-item>
            <el-form-item label="真实姓名">
              <span>{{ props.row.realname }}</span>
            </el-form-item>
            <el-form-item label="手机号">
              <span>{{ props.row.phone }}</span>
            </el-form-item>
            <el-form-item label="邮箱">
              <span>{{ props.row.email }}</span>
            </el-form-item>
            <el-form-item label="性别">
              <span>{{ props.row.sex == null ? '保密' : (props.row.sex === 1 ?  '女':'男' ) }}</span>
            </el-form-item>
            <el-form-item label="状态">
              <span>{{ props.row.locked === 1? '锁定' : '正常'}}</span>
            </el-form-item>
            <el-form-item label="创建时间">
              <!--时间戳转换-->
              <span>{{props.row.ctime | parseTime('{y}-{m}-{d} {h}:{i}')}}</span>
            </el-form-item>
          </el-form>
        </template>
      </el-table-column>
      <!--多选支持-->
      <el-table-column
        type="selection"
      >
      </el-table-column>
      <!--自定义索引-->
      <el-table-column
        type="index"
        label="序号"
        align="center"
        :index="indexMethod">
      </el-table-column>
      <el-table-column
        sortable
        prop="id"
        label="用户id"
      >
      </el-table-column>
      <el-table-column
        sortable
        prop="username"
        label="用户名"
      >
      </el-table-column>
      <el-table-column
        sortable
        prop="sex"
        label="性别"
      >
        <template slot-scope="props">
          {{ props.row.sex == null ? '保密' : (props.row.sex === 1 ?  '女':'男' ) }}
        </template>
      </el-table-column>
      <el-table-column
        sortable
        prop="locked"
        label="状态"
      >
        <template slot-scope="props">
          <el-button v-if="props.row.locked === 0" size="mini" disabled type="success">正常
          </el-button>
          <el-button v-else disabled size="mini" type="danger">禁用
          </el-button>
        </template>
      </el-table-column>
      <!--操作按钮-->
      <el-table-column align="center" :label="$t('table.actions')" width="230" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <!--编辑-->
          <el-button type="primary" size="mini" @click="handleUpdate(scope.row)">{{$t('table.edit')}}</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!--分页组件-->
    <div class="pagination-container">
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="current_page"
        :page-sizes="page_sizes"
        :page-size="page_size"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total_size">
      </el-pagination>
    </div>
    <!--添加修改用户-->
    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
      <el-form :rules="rules" ref="info" :model="info" label-position="right" label-width="100px" style='width: 400px; margin-left:50px;'>
        <!--prop用于进行表单校验-->
        <el-form-item label="用户名" prop="username">
          <el-input v-model="info.username"></el-input>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="info.email"></el-input>
        </el-form-item>
        <el-form-item label="手机号" prop="phone">
          <el-input v-model="info.phone"></el-input>
        </el-form-item>
        <el-form-item v-if="dialogStatus=='create'" label="密码" prop="password">
          <el-input type="password" v-model="info.password"></el-input>
        </el-form-item>
        <el-form-item v-if="dialogStatus=='create'" label="重复密码" prop="repeatPassword">
          <el-input type="password" v-model="info.repeatPassword"></el-input>
        </el-form-item>
        <el-form-item label="真实姓名" prop="realname">
          <el-input v-model="info.realname"></el-input>
        </el-form-item>
        <el-form-item label="性别" prop="sex">
          <el-select clearable style="width: 110px" class="filter-item" v-model="info.sex" :placeholder="'性别'">
            <el-option v-for="item in sex" :key="item" :label="item == 1 ? '女':'男'" :value="item">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item v-if="dialogStatus=='update'" label="状态" prop="locked">
          <el-select clearable style="width: 110px" class="filter-item" v-model="info.locked" :placeholder="'状态'">
            <el-option v-for="item in locked" :key="item" :label="item == 1 ? '锁定':'正常'" :value="item">
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">{{$t('table.cancel')}}</el-button>
        <el-button v-if="dialogStatus=='create'" type="primary" @click="createData">{{$t('table.confirm')}}</el-button>
        <el-button v-else type="primary" @click="updateData">{{$t('table.confirm')}}</el-button>
      </div>
    </el-dialog>
    <el-dialog title="编辑组织" :visible.sync="dialogOrgVisible">
      <el-transfer
        @change="joinOrgChange"
        filterable
        filter-placeholder="请输入组织名称"
        :titles="['可选组织', '加入的组织']"
        :button-texts="['退出组织', '加入组织']"
        :props="{
          key: 'id',
          label: 'name'
         }"
        v-model="joinOrg"
        :data="allOrg">
      </el-transfer>
    </el-dialog>
    <!--添加角色-->
    <el-dialog title="编辑角色" :visible.sync="dialogRoleVisible">
      <el-transfer
        @change="joinRoleChange"
        filterable
        filter-placeholder="请输入角色名称"
        :titles="['可选的角色', '已拥有的角色']"
        :button-texts="['取消角色', '添加角色']"
        :props="{
          key: 'id',
          label: 'name'
         }"
        v-model="joinRole"
        :data="allRole">
      </el-transfer>
    </el-dialog>
  </div>
</template>


<script>
  import waves from '@/directive/waves' // 水波纹指令
  import { parseTime } from '@/utils'
  import { add, getByCondition, deleteByIds, updateSelectiveById, addRoles, deleteRoles } from '@/api/upms/user'
  import { getByCondition as getAllOrg, getOrgByUserId } from '@/api/upms/organization'
  import { add as addorg, deleteByIds as deleteBatch } from '@/api/upms/organizationUser'
  import { getByCondition as getAllRole, getUserRole as getByRoleUser } from '@/api/upms/role'
  export default{
    directives: {
      waves
    },
    data() {
      return {
        tableData: null, // 组织查询的数据
        current_page: 1,
        page_sizes: [5, 10, 15, 20, 50],
        page_size: 5,
        total_size: undefined,
        listLoading: false,
        sex: [ // 描述状态
          0,
          1
        ],
        locked: [
          0,
          1
        ],
        info: {
          id: undefined, // 用于添加和编辑
          username: undefined,
          password: undefined,
          repeatPassword: undefined,
          email: undefined,
          sex: undefined,
          phone: undefined,
          locked: undefined
        },
        query: { // 用于查询
          username: undefined,
          realname: undefined,
          email: undefined,
          sex: undefined,
          org: undefined,
          phone: undefined,
          organizationId: undefined
        },
        dialogRoleVisible: false, // 添加角色的会话窗口
        dialogFormVisible: false, // 添加更新组织的会话窗口
        dialogStatus: undefined, // 会话的状态,是创建还是修改
        dialogOrgVisible: false,
        textMap: {
          update: '编辑',
          create: '添加'
        },
        downloadLoading: false,
        multipleSelection: [],
        rules: {
          username: [
            { required: true, message: '请输入用户名', trigger: 'blur' }
          ],
          password: [
            { required: true, message: '请输入密码', trigger: 'blur' }
          ],
          email: [
            { required: true, message: '请输入邮箱', trigger: 'blur' },
            { type: 'email', message: '请输入正确的邮箱', trigger: 'blur' }
          ],
          repeatPassword: [
            { required: true, message: '请确认输入密码', trigger: 'blur' }
          ]
        },
        allOrg: [], // 查询出来的所有的组织
        joinOrg: [], // 用户加入的组织
        joinOrgBak: [],
        orgs: [],
        allRole: [],
        joinRole: [],
        joinRoleBak: [],
        roles: []
      }
    },
    methods: {
      deepClon(obj) { // 深度克隆对象
        const proto = Object.getPrototypeOf(obj)
        return Object.assign({}, Object.create(proto), obj)
      },
      indexMethod(index) { // 自定义序号
        return this.page_size * (this.current_page - 1) + index + 1
      },
      handleCreate() {
        // 初始化数据
        for (var item in this.info) {
          this.info[item] = undefined
        }
        // 清除表单校验结果
        if (this.$refs['info']) {
          this.$refs['info'].clearValidate()
        }
        this.dialogStatus = 'create'
        this.dialogFormVisible = true
      },
      createData() {
        this.$refs.info.validate((validate) => {
          if (validate) {
            if (this.info.password === this.info.repeatPassword) {
              add(this.info).then(response => {
                if (response.data.code === 0) {
                  this.dialogFormVisible = false
                  this.$message({
                    message: '添加成功',
                    type: 'success'
                  })
                  this.getList()
                } else {
                  this.$message({
                    message: '添加失败',
                    type: 'error'
                  })
                }
              })
            } else {
              this.$message({
                message: '两次输入密码不一致,请重新输入!',
                type: 'info'
              })
            }
          }
        })
      },
      handleUpdate(value) { // 更新
        if (this.$refs['info']) {
          this.$refs['info'].clearValidate()
        }
        // 一定要深度克隆对象,不然容易出bug.比如先编辑然后添加
        this.info = this.deepClon(value)
        this.dialogStatus = 'update'
        this.dialogFormVisible = true
      },
      updateData() {
        this.$refs['info'].validate((validate) => {
          if (validate) {
            // 更新数据
            updateSelectiveById(this.info).then(response => {
              if (response.data.code === 0) {
                this.dialogFormVisible = false
                this.$message({
                  message: '更新信息成功',
                  type: 'success'
                })
                this.getList()
              } else {
                this.$message({
                  message: '更新信息失败',
                  type: 'error'
                })
              }
            })
          } else {
            this.$message({
              message: '请按提示填入正确的表单信息',
              type: 'info'
            })
          }
        })
      },
      handleDelete() {
        this.$confirm('此操作将永久删除该信息, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          if (this.multipleSelection.length < 1) {
            this.$message({
              message: '请选择要删除的组织',
              type: 'info'
            })
          }
          // 传入数组
          const ids = []
          const data = this.multipleSelection
          data.forEach((item) => {
            ids.push(item.id)
          })
          this.deleteData(ids).then(response => {
            if (response.data.code === 0) {
              this.$message({
                type: 'success',
                message: '删除成功!'
              })
            } else {
              this.$message({
                type: 'error',
                message: '删除失败!'
              })
            }
          })
        })
      },
      deleteData(ids) {
        // 删除系统
        deleteByIds(ids).then(response => {
          if (response.data.code === 0) {
            this.$message({
              message: '删除成功',
              type: 'success'
            })
            this.getList()
          } else {
            this.$message({
              message: '删除失败',
              type: 'error'
            })
          }
        })
      },
      getList() {
        this.listLoading = true
        // 加载列表
        getByCondition(this.query, this.current_page, this.page_size, 'username_asc').then(response => {
          this.listLoading = false
          if (response.data.code === 0) {
            const data = response.data.data
            this.tableData = data.list
            this.total_size = data.total
          } else {
            this.$message({
              message: '加载信息失败',
              type: 'error'
            })
          }
        })
      },
      handleSizeChange(pageSize) {
        if (pageSize === this.page_size) {
          return
        }
        this.page_size = pageSize
        this.getList()
      },
      handleCurrentChange(pageNum) {
        if (pageNum === this.current_page) {
          return
        }
        this.current_page = pageNum
        this.getList()
      },
      handleSelectionChange(value) {
        this.multipleSelection = value
      },
      parseTime(val) {
        return parseTime(val)
      },
      editOrg() {
        if (this.multipleSelection.length !== 1) {
          this.$message({
            message: '请选择一个用户进行编辑',
            type: 'info'
          })
        } else {
          const data = this.multipleSelection[0]
          this.allOrg = []
          getAllOrg({}, 1, 9999, 'name_asc').then(response => {
            if (response.data.code === 0) {
              this.allOrg = response.data.data.list
              this.joinOrg = []
              this.joinOrgBak = []
              getOrgByUserId(data.id).then(response => {
                this.dialogOrgVisible = true
                if (response.data.code === 0) {
                  response.data.data.forEach(item => {
                    this.joinOrg.push(item.id)
                    this.joinOrgBak.push(item.id)
                  })
                } else {
                  this.$message({
                    message: '编辑组织失败',
                    type: 'warning'
                  })
                }
              })
            } else {
              this.$message({
                message: '编辑组织失败',
                type: 'warning'
              })
            }
          })
        }
      },
      joinOrgChange(keys, direction) {
        if (direction === 'right') {
          const add = []
          const data = {}
          data.userId = this.multipleSelection[0].id
          const joinOrgBak = this.joinOrgBak
          keys.forEach(item => {
            joinOrgBak.indexOf(item) >= 0 ? '' : add.push(item)
          })
          data.organizationIds = add
          this.joinOrgBak = keys
          addorg(data).then(response => {
            if (response.data.code !== 0) {
              this.$message({
                message: '加入组织失败',
                type: 'warning'
              })
            }
          })
        } else {
          const data = {}
          const removeOrg = []
          this.joinOrgBak.forEach(item => {
            keys.indexOf(item) >= 0 ? '' : removeOrg.push(item)
          })
          data.userId = this.multipleSelection[0].id
          data.organizationIds = removeOrg
          this.joinOrgBak = keys
          deleteBatch(data).then(response => {
            if (response.data.code !== 0) {
              this.$message({
                message: '退出组织失败',
                type: 'warning'
              })
            }
          })
        }
      },
      /**
       * keys 是发生改变后右边的key的值
       * @param keys
       * @param direction
       */
      joinRoleChange(keys, direction) {
        // 给用户添加角色
        if (direction === 'right') {
          const user = []
          const addRole = []
          user.userId = this.multipleSelection[0].id
          const joinRoleBak = this.joinRoleBak
          // 遍历出要添加角色的key
          keys.forEach(item => {
            joinRoleBak.indexOf(item) >= 0 ? '' : addRole.push(item)
          })
          this.joinRoleBak = keys
          // 更新拥有的角色
          addRoles(user.userId, addRole).then(response => {
            if (response.data.code !== 0) {
              this.$message({
                message: '添加角色失败',
                type: 'warning'
              })
            }
          })
        } else {
          const user = []
          const removeRoles = []
          user.userId = this.multipleSelection[0].id
          this.joinRoleBak.forEach(item => {
            keys.indexOf(item) >= 0 ? '' : removeRoles.push(item)
          })
          this.joinRoleBak = keys
          deleteRoles(user.userId, removeRoles).then(response => {
            if (response.data.code !== 0) {
              this.$message({
                message: '取消角色失败',
                type: 'warning'
              })
            }
          })
        }
      },
      handlerGrantAuthorization() {
        // 检查用户是否选择了一个角色
        if (this.multipleSelection.length !== 1) {
          this.$message({
            type: 'info',
            message: '请选择一个用户'
          })
        } else {
          const user = this.multipleSelection[0]
          getAllRole({}, 1, 9999, 'name_asc').then(response => {
            // 是否获取数据成功
            if (response.data.code === 0) {
              const data = response.data.data
              this.allRole = data.list
              getByRoleUser(user.id).then(response => {
                // 获取用户拥有的角色成功
                if (response.data.code === 0) {
                  response.data.data.forEach(item => {
                    this.joinRole.push(item.id)
                    this.joinRoleBak.push(item.id)
                  })
                } else {
                  this.$message({
                    messgae: '加载用户角色失败',
                    type: 'warning'
                  })
                }
              })
            } else {
              this.$message({
                message: '加载角色失败',
                type: 'warning'
              })
            }
          })
          this.dialogRoleVisible = true
        }
      },
      remoteMethod(val) {
        if (val == null) {
          return
        }
        const data = {}
        data.name = val
        getAllOrg(data, 1, 9999, 'name_asc').then(response => {
          if (response.data.code === 0) {
            this.orgs = response.data.data.list
          } else {
            this.$message({
              message: '加载组织失败',
              type: 'warning'
            })
          }
        })
      }
    },
    created() {
      this.getList()
    }
  }
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
  .tree-container{
    border: 1px dashed #85bbd2;
    border-radius: 2px;
    padding: 10px;
    text-align: center;
    min-height: 500px;
    .tree-title{
      display: inline-block;
      height: 40px;
      padding: 10px;
      color: #999999;
    }
  }
  .demo-table-expand {
    font-size: 0;
    label {
      width: 90px;
      color: #99a9bf;
    }
    .el-form-item {
      margin-right: 0;
      margin-bottom: 0;
      width: 50%;
    }
  }
</style>
